home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / macabuse / src / view.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-20  |  27.4 KB  |  1,221 lines

  1. #include "system.h"
  2. #include "view.hpp"
  3. #include "lisp.hpp"
  4. #include "jwindow.hpp"
  5. #include "config.hpp"
  6. #include "scroller.hpp"
  7. #include "id.hpp"
  8. #include "dev.hpp"
  9. #include "jrand.hpp" 
  10. #include "dprint.hpp"
  11. #include "transp.hpp"
  12. #include "clisp.hpp"
  13. #include "demo.hpp"
  14. #include "sbar.hpp"
  15. #include "nfserver.hpp"
  16. #include "chat.hpp"
  17.  
  18. #define SHIFT_DOWN_DEFAULT 15
  19. #define SHIFT_RIGHT_DEFAULT 0
  20.  
  21. extern window_manager *eh;
  22. view *player_list=NULL;
  23. int morph_sel_frame_color;
  24.  
  25. view::~view()
  26. {
  27.   if (local_player()) 
  28.     sbar.associate(NULL);
  29.  
  30.   if (total_weapons)
  31.   {
  32.     jfree(weapons);
  33.     jfree(last_weapons);
  34.   }
  35. }
  36.  
  37.  
  38. extern uchar bright_tint[256];
  39.  
  40. void view::add_ammo(int weapon_type, int total)
  41. {  
  42.   if (weapon_type>=total_weapons || weapon_type<0)
  43.   {
  44.     dprintf("weapon out of range\n");
  45.     return ;
  46.   }
  47.   if (weapons[weapon_type]==-1) return ;   // don't have weapon yet, can't give ammo
  48.   int rf=0;
  49.  
  50.   weapons[weapon_type]+=total;
  51.   if (weapons[weapon_type]<0)  
  52.     weapons[weapon_type]=0;  
  53.  
  54.   if (weapons[weapon_type]>999)
  55.     weapons[weapon_type]=999;
  56.  
  57.   if (weapon_total(current_weapon)==0 && current_weapon)
  58.   {
  59.     suggest.send_weapon_change=1;
  60.     if (DEFINEDP(symbol_value(l_switch_to_powerful)) && symbol_value(l_switch_to_powerful))
  61.     {
  62.       int x=total_weapons-1;
  63.       while (x>0 && (x==3 || weapons[x]<=0)) x--;         
  64.       suggest.new_weapon=x;
  65.     } else
  66.       suggest.new_weapon=0;
  67.   }
  68.  
  69. }
  70.  
  71. void view::give_weapon(int type) 
  72.   if (type>=total_weapons || type<0)
  73.   {
  74.     dprintf("weapon out of range\n");
  75.     return ;
  76.   }
  77.   if (weapons[type]==-1) 
  78.   { 
  79.     weapons[type]=0; 
  80.     sbar.need_refresh();
  81.   }
  82. }
  83.  
  84. int view::weapon_total(int type)
  85. {
  86.   if (type>=total_weapons || type<0)
  87.   {
  88.     dprintf("weapon out of range\n");
  89.     return 0;
  90.   }
  91.   if (god) return 100;
  92.   else if (weapons[type]==-1) return 0;
  93.   else return weapons[type];
  94. }
  95.  
  96.  
  97. long view::xoff()
  98. {
  99.   if (focus)
  100.   {
  101.     int x=last_x-(cx2-cx1+1)/2+shift_right+pan_x;
  102.     if (x<0) return 0;
  103.     else return x;
  104.   } else return pan_x;
  105. }
  106.  
  107. long view::interpolated_xoff()
  108. {
  109.   if (focus)
  110.   {
  111.     int x=(last_last_x+last_x)/2-(cx2-cx1+1)/2+shift_right+pan_x;
  112.     if (x<0) return 0;
  113.     else return x;
  114.   } else return pan_x;
  115. }
  116.  
  117.  
  118. long view::yoff()
  119. {
  120.   if (focus)
  121.   {
  122.     int y=last_y-(cy2-cy1+1)/2-shift_down+pan_y;
  123.     if (y<0) return 0;
  124.     else return y;
  125.   } else return pan_y;
  126. }
  127.  
  128.  
  129. long view::interpolated_yoff()
  130. {
  131.   if (focus)
  132.   {
  133.     int y=(last_y+last_last_y)/2-(cy2-cy1+1)/2-shift_down+pan_y;
  134.     if (y<0) return 0;
  135.     else return y;
  136.   } else return pan_y;
  137. }
  138.  
  139.  
  140. void view::update_scroll()
  141. {
  142.   if (focus)
  143.   {
  144.     last_last_x=last_x;
  145.     last_last_y=last_y;
  146.     if (focus->x>last_x)
  147.     {
  148.       if (focus->x-last_x>=no_xright)
  149.         last_x=focus->x-no_xright;
  150.     } else if (focus->x<last_x)
  151.     {
  152.       if (last_x-focus->x>=no_xleft)
  153.         last_x=focus->x+no_xleft;
  154.     }
  155.     if (focus->y>last_y)
  156.     {
  157.       if (focus->y-last_y>=no_ybottom)
  158.         last_y=focus->y-no_ybottom;
  159.     } else if (focus->y<last_y)
  160.     {
  161.       if (last_y-focus->y>=no_ytop)
  162.         last_y=focus->y+no_ytop;
  163.     }
  164.   }
  165. }
  166.  
  167. char cur_user_name[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  168.  
  169. #ifdef __WATCOMC__
  170. char *get_login()
  171. {  if (cur_user_name[0]) return cur_user_name; else return "DOS user"; }
  172.  
  173. #include <dos.h>
  174. #elif defined( __MAC__ )
  175.  
  176. char *get_login()
  177. {  if (cur_user_name[0]) return cur_user_name; else return "Mac user"; }
  178.  
  179. #else
  180. char *get_login()
  181. {  if (cur_user_name[0]) return cur_user_name; else return (getlogin() ? getlogin() : "unknown"); }
  182.  
  183. #endif
  184.  
  185. void set_login(char *name)
  186. { strncpy(cur_user_name,name,20); }
  187.  
  188. view::view(game_object *Focus, view *Next, int number)
  189.   chat_buf[0]=0; 
  190.  
  191.   draw_solid=-1;
  192.   no_xleft=0;
  193.   no_xright=0;
  194.   no_ytop=0;
  195.   no_ybottom=0;
  196.   if (Focus)
  197.   {
  198.     last_x=Focus->x;
  199.     last_y=Focus->y;
  200.   } else
  201.   {
  202.     last_x=last_y=0;
  203.   }
  204.  
  205.   last_last_x=last_x;
  206.   last_last_y=last_y;
  207.   last_hp=last_ammo=-1;
  208.   last_type=-1;
  209.   tsecrets=secrets=0;
  210.   tkills=kills=0;
  211.  
  212.   reset_keymap();
  213.  
  214.   ambient=32;
  215.   current_weapon=0;
  216.  
  217.   strcpy(name,get_login());
  218.   suggest.send_view=0;
  219.   suggest.send_weapon_change=0;
  220.  
  221.  
  222.   god=0;
  223.  
  224.   player_number=number;
  225.   set_size();
  226.  
  227.   focus=Focus;
  228.   next=Next;
  229.   shift_down=SHIFT_DOWN_DEFAULT;
  230.   shift_right=SHIFT_RIGHT_DEFAULT;
  231.   x_suggestion=0;
  232.   y_suggestion=0;
  233.   b1_suggestion=0;
  234.   b2_suggestion=0;
  235.   b3_suggestion=0;
  236.   b4_suggestion=0;
  237.   pointer_x=0;
  238.   pointer_y=0;
  239.  
  240.   pan_x=0;
  241.   pan_y=0;
  242.   last_type=0;
  243.   freeze_time=0;
  244.  
  245.   if (total_weapons)
  246.   {
  247.     weapons=(long *)jmalloc(total_weapons*sizeof(long),"weapon array");
  248.     last_weapons=(long *)jmalloc(total_weapons*sizeof(long),"last weapon array");
  249.     memset(weapons,0xff,total_weapons*sizeof(long));   // set all to -1
  250.     memset(last_weapons,0xff,total_weapons*sizeof(long));   // set all to -1  
  251.   }
  252.  
  253.   if (total_weapons)
  254.     weapons[0]=0;
  255.   if (local_player())
  256.     sbar.associate(this);
  257.   sbar.need_refresh();
  258. }
  259.  
  260. long view::x_center() 
  261. {
  262.   if (!focus)
  263.     return (cx1+cx2)/2;
  264.   else
  265.     return focus->x; 
  266. }   
  267.  
  268. long view::y_center() 
  269.   if (!focus)
  270.     return (cy1+cy2)/2;
  271.   else
  272.     return focus->y; 
  273. }
  274.  
  275. void view::draw_character_damage()
  276. {   
  277.   if (focus && drawable())
  278.   {
  279.     if (last_hp!=focus->hp()) draw_hp();
  280.     int i;
  281.     for (i=0;i<total_weapons;i++)
  282.       if (weapons[i]!=last_weapons[i])
  283.       {
  284.     last_weapons[i]=weapons[i];
  285.         sbar.draw_ammo(screen,i,weapons[i],current_weapon==i);
  286.       }
  287.   }
  288. }
  289.  
  290.  
  291.  
  292. ushort make_sync()
  293. {
  294.   ushort x=0;
  295.   if (!current_level) return 0;
  296.   if (current_level)
  297.   {
  298.     view *f=player_list;
  299.     for (;f;f=f->next)
  300.     {
  301.       if (f->focus)
  302.       {
  303.     x^=(f->focus->x&0xffff);
  304.     x^=(f->focus->y&0xffff);
  305.       }
  306.     }
  307.   }
  308.   x^=rand_on;
  309.  
  310.   return x;
  311. }
  312.  
  313.  
  314.  
  315. void view::get_input()
  316. {
  317.   int sug_x,sug_y,sug_b1,sug_b2,sug_b3,sug_b4;
  318.   long sug_px,sug_py;
  319.  
  320.  
  321.   if (the_game->key_down(lnumber_value(symbol_value(l_left_key))))
  322.     sug_x=-1;
  323.   else if (the_game->key_down(lnumber_value(symbol_value(l_right_key))))
  324.     sug_x=1;
  325.   else sug_x=0;
  326.  
  327.   if (the_game->key_down(lnumber_value(symbol_value(l_up_key))))
  328.     sug_y=-1;
  329.   else if (the_game->key_down(lnumber_value(symbol_value(l_down_key))))
  330.     sug_y=1;
  331.   else sug_y=0;
  332.  
  333.   if ((last_demo_mbut&2) || the_game->key_down(lnumber_value(symbol_value(l_special_key))))
  334.     sug_b1=1;
  335.   else sug_b1=0;
  336.  
  337.   if (last_demo_mbut&1)
  338.     sug_b2=1;
  339.   else sug_b2=0;
  340.  
  341.   sug_b3=sug_b4=0;
  342.   the_game->mouse_to_game(last_demo_mx,last_demo_my,sug_px,sug_py,this);
  343.  
  344.  
  345.   /*
  346.  
  347.   if (DEFINEDP(symbol_function(l_get_local_input)))
  348.   {
  349.     void *ret=eval_function((lisp_symbol *)l_get_local_input,NULL);
  350.     sug_x=lnumber_value(CAR(ret));  ret=CDR(ret);
  351.     sug_y=lnumber_value(CAR(ret));  ret=CDR(ret);
  352.     if (CAR(ret)) sug_b1=1; else sug_b1=0; ret=CDR(ret);
  353.     if (CAR(ret)) sug_b2=1; else sug_b2=0;  ret=CDR(ret);
  354.     int x=lnumber_value(CAR(ret)); ret=CDR(ret);
  355.     if (x<0) sug_b3=1; else sug_b3=0;
  356.     if (x>0) sug_b4=1; else sug_b4=0;    
  357.     
  358.     long bx=lnumber_value(CAR(ret));  ret=CDR(ret);
  359.     long by=lnumber_value(CAR(ret));  ret=CDR(ret);
  360.     the_game->mouse_to_game(bx,by,sug_px,sug_py,this);
  361.  
  362.   } else
  363.   {
  364.     get_movement(0,sug_x,sug_y,sug_b1,sug_b2,sug_b3,sug_b4);
  365.     if (focus)
  366.     {
  367.       the_game->mouse_to_game(last_demo_mx,last_demo_my,sug_px,sug_py,this);
  368.       if (last_demo_mbut&1) sug_b2=1;
  369.       if (last_demo_mbut&2) sug_b1=1;
  370.     } else sug_px=sug_py=0;
  371.   }
  372.   */
  373.  
  374.   if (view_changed())
  375.   {
  376.     base->packet.write_byte(SCMD_VIEW_RESIZE);
  377.     base->packet.write_byte(player_number);
  378.     base->packet.write_long(suggest.cx1);
  379.     base->packet.write_long(suggest.cy1);
  380.     base->packet.write_long(suggest.cx2);
  381.     base->packet.write_long(suggest.cy2);
  382.  
  383.     base->packet.write_long(suggest.pan_x);
  384.     base->packet.write_long(suggest.pan_y);
  385.     base->packet.write_long(suggest.shift_down);
  386.     base->packet.write_long(suggest.shift_right);
  387.   }
  388.  
  389.   if (weapon_changed())
  390.   {
  391.     base->packet.write_byte(SCMD_WEAPON_CHANGE);
  392.     base->packet.write_byte(player_number);
  393.     base->packet.write_long(suggest.new_weapon);
  394.   }
  395.  
  396.   base->packet.write_byte(SCMD_SET_INPUT);
  397.   base->packet.write_byte(player_number);
  398.  
  399.  
  400.   uchar mflags=0;
  401.   if (sug_x>0)
  402.     mflags|=1;
  403.   else if (sug_x<0)
  404.     mflags|=2;
  405.  
  406.   if (sug_y>0)
  407.     mflags|=4;
  408.   else if (sug_y<0)
  409.     mflags|=8;
  410.  
  411.   if (sug_b1) mflags|=16;
  412.   if (sug_b2) mflags|=32;
  413.   if (sug_b3) mflags|=64;
  414.   if (sug_b4) mflags|=128;
  415.  
  416.   base->packet.write_byte(mflags);
  417.  
  418.   base->packet.write_short((ushort)((short)sug_px));
  419.   base->packet.write_short((ushort)((short)sug_py));
  420.  
  421. }
  422.  
  423.  
  424. void view::add_chat_key(int key)  // return string if buf is complete
  425. {
  426.   int len=strlen(chat_buf);
  427.   if (key==JK_BACKSPACE)
  428.   {
  429.     if (len)
  430.     {
  431.       chat_buf[len-1]=0;
  432.       if (local_player() && chat)
  433.         chat->draw_user(chat_buf);
  434.     }
  435.   } else if (key!=JK_ENTER)
  436.   {
  437.     chat_buf[len]=key;
  438.     chat_buf[len+1]=0;
  439.     if (local_player() && chat)
  440.       chat->draw_user(chat_buf);
  441.   }
  442.  
  443.   if (len>38 || key==JK_ENTER)
  444.   {
  445.     if (DEFINEDP(symbol_function(l_chat_input)))
  446.     {
  447.       game_object *o=current_object;
  448.       current_object=focus;
  449.  
  450.       void *m=mark_heap(TMP_SPACE);
  451.       void *list=NULL;
  452.       push_onto_list(new_lisp_string(chat_buf),list);       
  453.       eval_function((lisp_symbol *)l_chat_input,list);
  454.       restore_heap(m,TMP_SPACE);
  455.  
  456.       current_object=o;
  457.  
  458.     } else
  459.     {           
  460.       if (chat)
  461.         chat->put_all(chat_buf);
  462.     }
  463.     chat_buf[0]=0;
  464.     if (local_player() && chat)
  465.       chat->draw_user(chat_buf);
  466.   }
  467. }
  468.  
  469. int view::process_input(char cmd, uchar *&pk)   // return 0 if something went wrong
  470. {
  471.   switch (cmd)
  472.   {
  473.     case SCMD_CHAT_KEYPRESS :
  474.     {
  475.       add_chat_key(*(pk++));
  476.     } break;
  477.     case SCMD_VIEW_RESIZE :
  478.     { 
  479.       long x[8];
  480.       memcpy(x,pk,8*4);  pk+=8*4;
  481.       /*      cx1=lltl(x[0]);
  482.       cy1=lltl(x[1]);
  483.       cx2=lltl(x[2]);
  484.       cy2=lltl(x[3]); */
  485.     
  486.       pan_x=lltl(x[4]);
  487.       pan_y=lltl(x[5]);
  488.       shift_down=lltl(x[6]);
  489.       shift_right=lltl(x[7]);
  490.       if (small_render)
  491.       {
  492.     small_render->resize(cx2-cx1+1,cy2-cy1+1);
  493.       }
  494.  
  495.       suggest.send_view=0;
  496.       if (local_player())
  497.         the_game->draw();
  498.       return 1;
  499.     }
  500.     case SCMD_WEAPON_CHANGE :
  501.     {
  502.       long x;
  503.       memcpy(&x,pk,4);  pk+=4;
  504.       current_weapon=lltl(x);
  505.  
  506.       if (local_player())
  507.         sbar.need_refresh();
  508.       suggest.send_weapon_change=0;
  509.       return 1;
  510.     } break;
  511.  
  512.     case SCMD_SET_INPUT :
  513.     {
  514.       uchar x=*(pk++);
  515.  
  516.       if (x&1) x_suggestion=1;
  517.       else if (x&2) x_suggestion=-1;
  518.       else x_suggestion=0;
  519.  
  520.       if (x&4) y_suggestion=1;
  521.       else if (x&8) y_suggestion=-1;
  522.       else y_suggestion=0;
  523.  
  524.       if (x&16) b1_suggestion=1; else b1_suggestion=0;
  525.       if (x&32) b2_suggestion=1; else b2_suggestion=0;
  526.       if (x&64) b3_suggestion=1; else b3_suggestion=0;
  527.       if (x&128) b4_suggestion=1; else b4_suggestion=0;
  528.  
  529.       ushort p[2];
  530.       memcpy(p,pk,2*2);  pk+=2*2;
  531.       
  532.       pointer_x=(short)(lstl(p[0]));
  533.       pointer_y=(short)(lstl(p[1]));
  534.     
  535.       return 1;
  536.     } break;
  537.     case SCMD_KEYPRESS : set_key_down(*(pk++),1); break;
  538.     case SCMD_EXT_KEYPRESS : set_key_down(*(pk++)+256,1); break;
  539.     case SCMD_KEYRELEASE : set_key_down(*(pk++),0); break;
  540.     case SCMD_EXT_KEYRELEASE : set_key_down(*(pk++)+256,0); break;
  541.   }
  542.   return 1;
  543. }
  544.  
  545. int view::local_player()
  546. {
  547.   return player_number==client_number();
  548. }
  549.  
  550. void view::next_weapon()
  551. {
  552.   int c=current_weapon;
  553.  
  554.   while (c<total_weapons-1)
  555.   {
  556.     c++;
  557.     if (weapon_total(c)>0)
  558.     {
  559.       suggest.send_weapon_change=1;
  560.       suggest.new_weapon=c;
  561.       return ;
  562.     }
  563.   }
  564.  
  565.   c=0;
  566.   while (c!=current_weapon)
  567.   {
  568.     if (weapon_total(c)>0)
  569.     {
  570.       suggest.send_weapon_change=1;
  571.       suggest.new_weapon=c;
  572.       return ;
  573.     }
  574.     c++;
  575.   }
  576. }
  577.  
  578. void view::last_weapon()
  579. {
  580.  
  581.   int c=current_weapon;
  582.  
  583.   while (c>=1)
  584.   {
  585.     c--;
  586.     if (weapon_total(c)>0 || c==0)
  587.     {
  588.       suggest.send_weapon_change=1;
  589.       suggest.new_weapon=c;
  590.       return ;
  591.     }
  592.   }
  593.  
  594.   c=total_weapons-1;
  595.   while (c!=current_weapon)
  596.   {
  597.     if (weapon_total(c)>0 || c==0)
  598.     {
  599.       suggest.send_weapon_change=1;
  600.       suggest.new_weapon=c;
  601.       return ;
  602.     }
  603.     c--;
  604.   }
  605.  
  606. }
  607.  
  608. int view::handle_event(event &ev)
  609. {
  610.   if (ev.type==EV_KEY)
  611.   {
  612.         if (ev.key == lnumber_value(symbol_value(l_weapon_left_key)))
  613.     {
  614.         if (total_weapons) 
  615.             last_weapon(); 
  616.         return 1; 
  617.     }
  618.          else if (ev.key == lnumber_value(symbol_value(l_weapon_right_key)))
  619.     { 
  620.         if (total_weapons) 
  621.             next_weapon(); 
  622.         return 1;
  623.     }
  624. #ifndef __MAC__
  625.         else if (ev.key >= '1' && ev.key <= '7')
  626.       { 
  627.           if (((dev&EDIT_MODE)==0) && (weapon_total(ev.key-'1')>0))
  628.         {
  629.                  suggest.send_weapon_change=1;
  630.                  suggest.new_weapon=ev.key-'1';
  631.         }
  632.       }
  633. #endif
  634.  }
  635.   return 0;
  636. }
  637.  
  638.  
  639. void view::draw_hp()
  640.   if (focus)
  641.   {
  642.     int h=focus->hp();    
  643.     last_hp=h;
  644.     sbar.draw_health(screen,focus->hp());
  645.   } else
  646.     sbar.draw_health(screen,0);
  647. }
  648.  
  649. int view::drawable()
  650. {  
  651.   return local_player();
  652. }
  653.  
  654.  
  655. void recalc_local_view_space()   // calculates view areas for local players, should be called 
  656.                                  // when adding or deleting local players
  657. {
  658.   if (screen)
  659.   {
  660.  
  661.     int Xres=small_render ? xres/2 : xres;
  662.     int Yres=small_render ? yres/2 : yres;
  663.  
  664.     int h=Yres;
  665.     int w=h*320/200,y=5;
  666.     if (w<300) w=300;
  667.  
  668.     for (view *f=player_list;f;f=f->next)
  669.     {
  670.       f->set_size();
  671.       /*
  672.       if (f->local_player())
  673.       {
  674.                 f->suggest.cx1=0;
  675.                 f->suggest.cx2=Xres;
  676. //                f->suggest.cx1=Xres/2-w/2;
  677. //                f->suggest.cx2=Xres/2+w/2;
  678. //                if (f->suggest.cx1<2) f->suggest.cx1=2;
  679. //                if (f->suggest.cx2>Xres-2) f->suggest.cx2=Xres-2;    
  680.             
  681.                 f->suggest.cy1=y;
  682.                 f->suggest.cy2=h-(total_weapons ? 33 : 0);
  683.             
  684.                 f->suggest.shift_down=f->shift_down;
  685.                 f->suggest.shift_right=f->shift_right;
  686.                 f->suggest.pan_x=f->pan_x;
  687.                 f->suggest.pan_y=f->pan_y;
  688.                 f->suggest.send_view=1;
  689.             
  690.                 if (!player_list->next)
  691.                 {
  692.                   f->cx1=f->suggest.cx1;
  693.                   f->cy1=f->suggest.cy1;
  694.                   f->cx2=f->suggest.cx2;
  695.                   f->cy2=f->suggest.cy2;
  696.                   f->suggest.send_view=0;
  697.                 }
  698.                 y+=h;
  699.       } */
  700.  
  701.  
  702.     }
  703.   }
  704.  
  705. }
  706.  
  707.  
  708. void set_local_players(int total)
  709. {
  710.   int rdw=0;
  711.   if (total<1) return ;
  712.  
  713.   view *last=NULL;
  714.   for (view *f=player_list;f;f=f->next)
  715.   {
  716.     if (total && f->local_player())
  717.       total--;
  718.     else if (!total && f->local_player())  // too many local players, delete this one
  719.     {
  720.       view *n=last->next;
  721.       while (n && !n->local_player()) n=n->next;  // find next local player
  722.  
  723.       if (last)
  724.         last->next=n;
  725.       else        
  726.       {
  727.     if (n)    // make sure we have at least one local player
  728.           player_list=n;
  729.       }            
  730.       last=f;
  731.       rdw=1;
  732.     }
  733.   }
  734.   
  735.   while (total)   // see if we need to add new players
  736.   {
  737.     game_object *o=create(current_start_type,50,50);    
  738.     view *v;
  739.     if (!player_list)
  740.     {
  741.       player_list=new view(o,NULL,0);
  742.       v=player_list;
  743.     }
  744.     else
  745.     {
  746.       view *f=player_list;
  747.       for (;f && f->next;f=f->next);        
  748.       f->next=new view(o,NULL,f->player_number+1);
  749.       v=f->next;
  750.     }
  751.  
  752.     v->set_size();
  753.  
  754.  
  755.     //  v->cx1=320/2-155; v->cy1=200/2-95; v->cx2=320/2+155; v->cy2=200/2+(total_weapons ? 60 : 95);
  756.     v->focus->set_controller(v);
  757.     total--;
  758.     rdw=1;
  759.   }  
  760.   if (rdw)
  761.     recalc_local_view_space();
  762. }
  763.  
  764.  
  765. int total_local_players()
  766. {
  767.   int t=0;
  768.   for (view *f=player_list;f;f=f->next) 
  769.     if (f->local_player()) t++;
  770.   return t;
  771. }
  772.  
  773.  
  774. void view::resize_view(long Cx1, long Cy1, long Cx2, long Cy2)
  775. {
  776.   if (cx1!=Cx1 || cx2!=Cx2 || cy1!=Cy1 || cy2!=Cy2)
  777.   {
  778.     cx1=Cx1; cy1=Cy1;
  779.     cx2=Cx2; cy2=Cy2;
  780.     if (playing_state(the_game->state) && local_player())
  781.       the_game->draw(0);
  782.   }
  783. }
  784.  
  785.  
  786. void view::set_input(int cx, int cy, int b1, int b2, int b3, int b4, int px, int py)
  787. {
  788.   x_suggestion=cx;
  789.   y_suggestion=cy;
  790.   b1_suggestion=b1;
  791.   b2_suggestion=b2;
  792.   b3_suggestion=b3;
  793.   b4_suggestion=b4;
  794.   pointer_x=px;
  795.   pointer_y=py;
  796. }
  797.  
  798.  
  799.  
  800. void view::reset_player()
  801. {
  802.   if (focus)
  803.   {
  804.     if (!player_list->next)
  805.       tkills=0;
  806.  
  807.     kills=0;
  808.  
  809.     game_object *start=current_level ? current_level->get_random_start(320,focus->controller()) : 0;
  810.     focus->defaults();
  811.     if (start)
  812.     {
  813.       focus->x=start->x;
  814.       focus->y=start->y;
  815.       dprintf("reset position to %d %d\n",start->x,start->y);
  816.     } 
  817.     focus->set_state(stopped);
  818.     memset(weapons,0xff,total_weapons*sizeof(long));   
  819.     memset(last_weapons,0xff,total_weapons*sizeof(long));   
  820.  
  821.     shift_down=SHIFT_DOWN_DEFAULT;
  822.     shift_right=SHIFT_RIGHT_DEFAULT;
  823.  
  824.     if (total_weapons)
  825.       weapons[0]=0;  // give him the first weapon
  826.     current_weapon=0;
  827.  
  828.     memset(focus->lvars,0,figures[focus->otype]->tv*4);
  829.     focus->set_aistate(0);
  830.     if (figures[focus->otype]->get_fun(OFUN_CONSTRUCTOR))
  831.     {
  832.       game_object *o=current_object;
  833.       current_object=focus;
  834.       eval_user_fun((lisp_symbol *)figures[focus->otype]->get_fun(OFUN_CONSTRUCTOR),NULL);
  835.       current_object=o;
  836.     }
  837.     sbar.redraw(screen);
  838.  
  839.     int i;
  840.     for (i=0;i<focus->total_objects();i++)   // reset the vars for the attached objects
  841.     {      
  842.       game_object *o=focus->get_object(i);
  843.       memset(o->lvars,0,figures[o->otype]->tv*4);
  844.     }
  845.  
  846.   }
  847. }
  848.  
  849.  
  850.  
  851.  
  852.  
  853. object_node *make_player_onodes(int player_num)
  854. {
  855.   object_node *first=NULL,*last;
  856.   for (view *o=player_list;o;o=o->next)
  857.   {
  858.     if (o->focus && (player_num==-1 || o->player_number==player_num))
  859.     {
  860.       if (!object_to_number_in_list(o->focus,first))
  861.       {
  862.     object_node *q=new object_node(o->focus,NULL);
  863.     if (first)
  864.       last->next=q;
  865.     else first=q;
  866.     last=q;
  867.       }
  868.       for (int i=0;i<o->focus->total_objects();i++)
  869.       {
  870.     game_object *p=o->focus->get_object(i);
  871.  
  872.     if (!object_to_number_in_list(p,first))
  873.     {
  874.       object_node *q=new object_node(p,NULL);
  875.       if (first)
  876.         last->next=q;
  877.       else first=q;
  878.       last=q;
  879.     }
  880.       }      
  881.     }
  882.   }
  883.   return first;
  884. }
  885.  
  886.  
  887.  
  888.  
  889. enum { V_CX1, V_CY1, V_CX2, V_CY2,
  890.        V_SHIFT_DOWN, V_SHIFT_RIGHT,
  891.        V_GOD,
  892.        V_PLAYER_NUMBER,
  893.        V_DRAW_SOLID,
  894.        V_LIVES,
  895.        V_CURRENT_WEAPON,
  896.        V_X_SUGGESTION, V_Y_SUGGESTION, V_B1_SUGGESTION, V_B2_SUGGESTION, V_B3_SUGGESTION, V_B4_SUGGESTION,
  897.        V_PAN_X, V_PAN_Y,
  898.        V_NO_XLEFT, V_NO_XRIGHT, V_NO_YTOP, V_NO_YBOTTOM,
  899.        V_LAST_X, V_LAST_Y, V_LAST_LEFT, V_LAST_RIGHT, V_LAST_UP, V_LAST_DOWN,
  900.        V_LAST_B1, V_LAST_B2, V_LAST_B3, V_LAST_B4,
  901.        V_LAST_HP,
  902.        V_SECRETS, V_KILLS, V_TSECRETS, V_TKILLS,
  903.        V_AMBIENT,
  904.        V_POINTER_X, V_POINTER_Y,
  905.        V_LAST_LAST_X, V_LAST_LAST_Y,
  906.        V_FREEZE_TIME };
  907.  
  908. #define TVV (V_FREEZE_TIME+1)
  909.  
  910. static char *vv_names[TVV]={
  911.   "view.cx1",  "view.cy1",  "view.cx2",  "view.cy2", 
  912.   "view.shift_down",  "view.shift_right",
  913.   "view.god",
  914.   "view.player_number",
  915.   "view.draw_solid",
  916.   "view.lives",
  917.   "view.current_weapon",
  918.   "view.x_suggestion",  "view.y_suggestion",  
  919.    "view.b1_suggestion",  "view.b2_suggestion",  "view.b3_suggestion",  "view.b4_suggestion",
  920.   "view.pan_x",  "view.pan_y",
  921.   "view.no_xleft",  "view.no_xright",  "view.no_ytop",  "view.no_ybottom",
  922.   "view.last_x",  "view.last_y",  "view.last_left",  "view.last_right",  "view.last_up",  "view.last_down", 
  923.   "view.last_b1",  "view.last_b2",  "view.last_b3",  "view.last_b4",
  924.   "view.last_hp",
  925.   "view.secrets",  "view.kills",  "view.tsecrets",  "view.tkills",
  926.   "view.ambient",
  927.   "view.pointer_x",  "view.pointer_y",
  928.   "view.last_last_x",  "view.last_last_y",
  929.   "view.freeze_time"
  930. };
  931.  
  932.  
  933. int total_view_vars() 
  934. { return TVV;
  935. }
  936.  
  937. char *get_view_var_name(int num)
  938. { return vv_names[num]; }
  939.  
  940. long view::get_view_var_value(int num)
  941. {
  942.   switch (num)
  943.   {
  944.     case V_CX1 : return cx1; break;
  945.     case V_CY1 : return cy1; break;
  946.     case V_CX2 : return cx2; break;
  947.     case V_CY2 : return cy2; break;
  948.     case V_SHIFT_DOWN : return shift_down; break;
  949.     case V_SHIFT_RIGHT : return shift_right; break;
  950.     case V_GOD : return god; break;
  951.     case V_PLAYER_NUMBER : return player_number; break;
  952.  
  953.     case V_DRAW_SOLID : return draw_solid; break;
  954.     case V_CURRENT_WEAPON : return current_weapon; break;
  955.     case V_X_SUGGESTION : return x_suggestion; break;
  956.     case V_Y_SUGGESTION : return y_suggestion; break;
  957.     case V_B1_SUGGESTION : return b1_suggestion; break;
  958.     case V_B2_SUGGESTION : return b2_suggestion; break;
  959.     case V_B3_SUGGESTION : return b3_suggestion; break;
  960.     case V_B4_SUGGESTION : return b4_suggestion; break;
  961.  
  962.     case V_PAN_X : return pan_x; break;
  963.     case V_PAN_Y : return pan_y; break;
  964.     case V_NO_XLEFT : return no_xleft; break;
  965.     case V_NO_XRIGHT : return no_xright; break;
  966.     case V_NO_YTOP : return no_ytop; break;
  967.     case V_NO_YBOTTOM : return no_ybottom; break;
  968.     case V_LAST_X : return last_x; break;
  969.     case V_LAST_Y : return last_y; break;
  970.     case V_LAST_LEFT : return last_left; break;
  971.     case V_LAST_RIGHT : return last_right; break;
  972.     case V_LAST_UP : return last_up; break;
  973.     case V_LAST_DOWN : return last_down; break;
  974.     case V_LAST_B1 : return last_b1; break;
  975.     case V_LAST_B2 : return last_b2; break;
  976.     case V_LAST_B3 : return last_b3; break;
  977.     case V_LAST_B4 : return last_b4; break;
  978.     case V_LAST_HP : return last_hp; break;
  979.     case V_SECRETS : return secrets; break;
  980.     case V_KILLS : return kills; break;
  981.     case V_TSECRETS : return tsecrets; break;
  982.     case V_TKILLS : return tkills; break;
  983.     case V_AMBIENT : return ambient; break;
  984.     case V_POINTER_X : return pointer_x; break;
  985.     case V_POINTER_Y : return pointer_y; break;
  986.     case V_LAST_LAST_X : return last_last_x; break;
  987.     case V_LAST_LAST_Y : return last_last_y; break;
  988.     case V_FREEZE_TIME : return freeze_time; break;
  989.   }
  990.   return 0;
  991. }
  992.  
  993.  
  994.  
  995. long view::set_view_var_value(int num, long x)
  996. {
  997.   switch (num)
  998.   {
  999.     /*    case V_CX1 : cx1=x; break;
  1000.     case V_CY1 : cy1=x; break;
  1001.     case V_CX2 : cx2=x; break;
  1002.     case V_CY2 : cy2=x; break; */
  1003.     case V_SHIFT_DOWN : shift_down=x; break;
  1004.     case V_SHIFT_RIGHT : shift_right=x; break;
  1005.     case V_GOD : god=x; break;
  1006.     case V_PLAYER_NUMBER : { player_number=x; if (local_player()) sbar.associate(this); }  break;
  1007.  
  1008.     case V_DRAW_SOLID : draw_solid=x; break;
  1009.     case V_CURRENT_WEAPON : { current_weapon=x; sbar.need_refresh(); } break;
  1010.     case V_X_SUGGESTION : x_suggestion=x; break;
  1011.     case V_Y_SUGGESTION : y_suggestion=x; break;
  1012.     case V_B1_SUGGESTION : b1_suggestion=x; break;
  1013.     case V_B2_SUGGESTION : b2_suggestion=x; break;
  1014.     case V_B3_SUGGESTION : b3_suggestion=x; break;
  1015.     case V_B4_SUGGESTION : b4_suggestion=x; break;
  1016.  
  1017.     case V_PAN_X : pan_x=x; break;
  1018.     case V_PAN_Y : pan_y=x; break;
  1019.     case V_NO_XLEFT : no_xleft=x; break;
  1020.     case V_NO_XRIGHT : no_xright=x; break;
  1021.     case V_NO_YTOP : no_ytop=x; break;
  1022.     case V_NO_YBOTTOM : no_ybottom=x; break;
  1023.     case V_LAST_X : last_x=x; break;
  1024.     case V_LAST_Y : last_y=x; break;
  1025.     case V_LAST_LEFT : last_left=x; break;
  1026.     case V_LAST_RIGHT : last_right=x; break;
  1027.     case V_LAST_UP : last_up=x; break;
  1028.     case V_LAST_DOWN : last_down=x; break;
  1029.     case V_LAST_B1 : last_b1=x; break;
  1030.     case V_LAST_B2 : last_b2=x; break;
  1031.     case V_LAST_B3 : last_b3=x; break;
  1032.     case V_LAST_B4 : last_b4=x; break;
  1033.  
  1034.     case V_LAST_HP : last_hp=x; break;
  1035.     case V_SECRETS : secrets=x; break;
  1036.     case V_KILLS : kills=x; break;
  1037.     case V_TSECRETS : tsecrets=x; break;
  1038.     case V_TKILLS : tkills=x; break;
  1039.     case V_AMBIENT : ambient=x; break;
  1040.     case V_POINTER_X : pointer_x=x; break;
  1041.     case V_POINTER_Y : pointer_y=x; break;
  1042.     case V_LAST_LAST_X : last_last_x=x; break; 
  1043.     case V_LAST_LAST_Y : last_last_y=x; break;
  1044.     case V_FREEZE_TIME : freeze_time=x; break;
  1045.   }
  1046.   return 1;
  1047. }
  1048.  
  1049.  
  1050. void view::configure_for_area(area_controller *a)
  1051. {
  1052.   if (a->ambient>=0 && a->ambient!=ambient)
  1053.   {
  1054.     if (ambient>a->ambient)
  1055.     {
  1056.       ambient-=a->ambient_speed;
  1057.       if (ambient<a->ambient) 
  1058.         ambient=a->ambient;
  1059.     }
  1060.     else 
  1061.     {
  1062.       ambient+=a->ambient_speed;
  1063.       if (ambient>a->ambient) 
  1064.         ambient=a->ambient;
  1065.     }    
  1066.   }
  1067.  
  1068.   if (!view_shift_disabled)
  1069.   {
  1070.     if (a->view_xoff!=pan_x)
  1071.     {
  1072.       if (pan_x>a->view_xoff)
  1073.       {
  1074.     pan_x-=a->view_xoff_speed;
  1075.     if (pan_x<a->view_xoff) 
  1076.         pan_x=a->view_xoff;
  1077.       }
  1078.       else
  1079.       {
  1080.     pan_x+=a->view_xoff_speed;
  1081.     if (pan_x>a->view_xoff) 
  1082.         pan_x=a->view_xoff;
  1083.       }
  1084.     }
  1085.  
  1086.     if (a->view_yoff!=pan_y)
  1087.     {
  1088.       if (pan_y>a->view_yoff)
  1089.       {
  1090.     pan_y-=a->view_yoff_speed;
  1091.     if (pan_y<a->view_yoff) 
  1092.         pan_y=a->view_yoff;
  1093.       }
  1094.       else
  1095.       {
  1096.     pan_y+=a->view_yoff_speed;
  1097.     if (pan_y>a->view_yoff) 
  1098.         pan_y=a->view_yoff;
  1099.       }
  1100.     }  
  1101.   }
  1102. }
  1103.  
  1104.  
  1105. void process_packet_commands(uchar *pk, int size)
  1106. {
  1107.   long sync_short=-1;
  1108.  
  1109.   if (!size) return ;
  1110.   pk[size]=SCMD_END_OF_PACKET;
  1111.  
  1112.   uchar cmd;
  1113.   int already_reloaded=0;
  1114.  
  1115.  
  1116.   do
  1117.   {
  1118.     cmd=*(pk++);
  1119.     switch (cmd)
  1120.     {
  1121.       case SCMD_WEAPON_CHANGE :
  1122.       case SCMD_SET_INPUT :
  1123.       case SCMD_VIEW_RESIZE :
  1124.       case SCMD_KEYPRESS :
  1125.       case SCMD_KEYRELEASE :
  1126.       case SCMD_EXT_KEYPRESS :
  1127.       case SCMD_EXT_KEYRELEASE :
  1128.       case SCMD_CHAT_KEYPRESS :
  1129.       {
  1130.     uchar player_num=*(pk++);
  1131.  
  1132.     view *v=player_list;
  1133.     for (;v && v->player_number!=player_num;v=v->next);
  1134.     if (v)
  1135.     {
  1136.       if (v->player_number==player_num)
  1137.       v->process_input(cmd,pk);
  1138.     }      
  1139.     else
  1140.     {
  1141.       dprintf("Evil error : bad player number in packet\n");
  1142.       return ;
  1143.     }
  1144.       } break;
  1145.       case SCMD_RELOAD :
  1146.       {
  1147.     if (!already_reloaded)
  1148.     {
  1149.       net_reload();
  1150.       already_reloaded=1;
  1151.     }
  1152.       } break;
  1153.  
  1154.       case SCMD_SYNC :
  1155.       {
  1156.     ushort x;
  1157.     memcpy(&x,pk,2);  pk+=2;
  1158.     x=lstl(x);
  1159.     if (demo_man.current_state()==demo_manager::PLAYING)
  1160.     sync_short=make_sync();
  1161.  
  1162.     if (sync_short==-1)
  1163.     sync_short=x;
  1164.     else if (x!=sync_short && !already_reloaded)
  1165.     {
  1166.       dprintf("out of sync %d (packet=%d, calced=%d)\n",current_level->tick_counter(),x,sync_short);
  1167.           dprintf("rand_on=%d\n",rand_on);
  1168.           int i=0;
  1169.           view *f=player_list;
  1170.           for (;f;f=f->next,i++)
  1171.           {
  1172.             if (f->focus)
  1173.               dprintf("player %d (x=%d,y=%d)\n",i,f->focus->x,f->focus->y);
  1174.           }
  1175.  
  1176.  
  1177.       if (demo_man.current_state()==demo_manager::NORMAL)
  1178.         net_reload();
  1179.       already_reloaded=1;
  1180.     }
  1181.       } break;
  1182.       case SCMD_DELETE_CLIENT :
  1183.       {
  1184.     uchar player_num=*(pk++);
  1185.     view *v=player_list,*last=NULL;
  1186.     for (;v && v->player_number!=player_num;v=v->next)
  1187.     last=v;
  1188.     if (!v)
  1189.     dprintf("evil : delete client %d, but no such client\n");
  1190.     else
  1191.     {
  1192.  
  1193.       // make a list of all objects associated with this player
  1194.       object_node *on=make_player_onodes(player_num);   
  1195.       while (on)
  1196.       {
  1197.         current_level->delete_object(on->me);
  1198.         object_node *last=on;
  1199.         on=on->next;
  1200.         delete last;
  1201.       }
  1202.  
  1203.       v->focus=NULL;
  1204.       if (last)
  1205.       last->next=v->next;
  1206.       else player_list=player_list->next;
  1207.  
  1208.       delete v;
  1209.     }
  1210.       } break;
  1211.       defualt :
  1212.       dprintf("Unknown net command %d\n",cmd);
  1213.  
  1214.     }
  1215.   } while (cmd!=SCMD_END_OF_PACKET);
  1216. }
  1217.